﻿using TrueSync;
using UnityEngine;

namespace HEFramework
{
    public static class AlertComponentSystem
    {
        [EntitySystem]
        public class AlertComponentAwakeSystem : AwakeSystem<AlertComponent, int>
        {
            protected override void Awake(AlertComponent _self, int _value)
            {
                var ac = _self.GetParentChild<AttributeComponent>();
                if (ac == null)
                {
                    return;
                }

                _self.SetType(_value);
                _self.SearchTime = Formula.TM(ac.Attribute.SEC_F);
            }
        }


        [EntitySystem]
        public class AlertComponentUpdateSystem : UpdateSystem<AlertComponent>
        {
            protected override void Update(AlertComponent _self)
            {
                var ac = _self.GetParentChild<AttributeComponent>();
                if (ac == null)
                {
                    return;
                }

                FP deltaTime = Time.deltaTime;

                //每过一段时间检查
                _self.SearchTime -= deltaTime;
                if (_self.SearchTime <= 0)
                {
                    _self.Search();
                    _self.SearchTime = Formula.TM(ac.Attribute.SEC_F);
                }
            }
        }


        [EntitySystem]
        public class AlertComponentDestroySystem : DestroySystem<AlertComponent>
        {
            protected override void Destroy(AlertComponent _self)
            {
                if (_self.Enemies != null)
                {
                    _self.Teams.Clear();
                    _self.Friends.Clear();
                    _self.Enemies.Clear();
                }
            }
        }


        public static void Search(this AlertComponent _self)
        {
            _self.Teams.Clear();
            _self.Friends.Clear();
            _self.Enemies.Clear();

            using ListObject<Entity> others = _self.GetScene().GetChildList<Entity>();

            if (others.Count > 0)
            {
                AttributeComponent acA = _self.GetParentChild<AttributeComponent>();
                TransformComponent tcA = _self.GetParentChild<TransformComponent>();

                //拥有属性组件与移动组件
                if (acA == null || tcA == null)
                {
                    return;
                }

                AttributeComponent acB;
                TransformComponent tcB;
                FP dis;
                for (int i = 0; i < others.Count; i++)
                {
                    acB = others[i].GetChild<AttributeComponent>();
                    tcB = others[i].GetChild<TransformComponent>();
                    //拥有属性组件
                    if (acB == null || tcB == null)
                    {
                        continue;
                    }

                    dis = TSVector.Distance(tcA.P, tcB.P);
                    //搜查距离
                    if (Formula.LG(acA.Attribute.SEC_RAG) >= dis)
                    {
                        //相同队伍跳过
                        if (acA.IsTeam(acB))
                        {
                            _self.Teams.Add(others[i]);
                        }

                        if (acA.IsFriend(acB))
                        {
                            _self.Friends.Add(others[i]);
                        }

                        if (acA.IsEnemy(acB))
                        {
                            _self.Enemies.Add(others[i]);
                        }
                    }
                }


                switch (_self.Type)
                {
                    case (int)eAlertType.Normal:
                        //是否还在警戒范围内
                        if (_self.IsTargetInAlert())
                        {
                            return;
                        }

                        _self.Target = null;
                        //1、选距离最近的
                        _self.SelectTargetByDistance();
                        //2、选仇恨值最高的
                        _self.SelectTargetByTRT();
                        break;
                    case (int)eAlertType.Nearest:
                        _self.Target = null;
                        //选距离最近的
                        _self.SelectTargetByDistance();
                        break;
                    case (int)eAlertType.TRTest:
                        _self.Target = null;
                        //选仇恨值最高的
                        _self.SelectTargetByDistance();
                        break;
                    case (int)eAlertType.Composite:
                        _self.Target = null;
                        //1、选距离最近的
                        _self.SelectTargetByDistance();
                        //2、选仇恨值最高的
                        _self.SelectTargetByTRT();
                        break;
                }
            }
        }

        public static void SetType(this AlertComponent _self, int _value)
        {
            _self.Type = _value;
            _self.Target = null;
        }

        public static bool IsAlert(this AlertComponent _self)
        {
            return _self.Target.Entity != null;
        }

        private static void SelectTargetByDistance(this AlertComponent _self)
        {
            var targets = _self.Enemies;
            FP dis = FP.MaxValue;
            TransformComponent tc = _self.GetParentChild<TransformComponent>();
            TransformComponent o_tc;
            for (int i = 0; i < targets.Count; i++)
            {
                var entity = targets[i].Entity;
                if (entity == null)
                {
                    continue;
                }

                o_tc = entity.GetChild<TransformComponent>();
                FP dis1 = TSVector.Distance(tc.P, o_tc.P);
                if (dis1 < dis)
                {
                    _self.Target = entity;
                    dis = dis1;
                }
            }
        }

        private static void SelectTargetByTRT(this AlertComponent _self)
        {
            if (_self.Enemies.Count <= 0)
            {
                return;
            }

            var targets = _self.Enemies;
            //如果当前没有目标 选择对象列表中的第一个当作目标
            if (_self.Target.Entity == null)
            {
                _self.Target = targets[0];
            }

            if (_self.Target.Entity == null)
            {
                return;
            }

            var oc = _self.Target.Entity.GetChild<AttributeComponent>();
            for (int i = 0; i < targets.Count; i++)
            {
                var entity = targets[i].Entity;
                if (entity == null)
                {
                    continue;
                }

                if (entity.GetChild<AttributeComponent>().TRT > oc.TRT)
                {
                    _self.Target = entity;
                    oc = _self.Target.Entity.GetChild<AttributeComponent>();
                }
            }
        }

        private static bool IsTargetInAlert(this AlertComponent _self)
        {
            var target = _self.Target.Entity;
            if (target == null)
            {
                return false;
            }

            bool isTrue = false;
            for (int i = 0; i < _self.Enemies.Count; i++)
            {
                var entity = _self.Enemies[i].Entity;
                if (entity == null)
                {
                    continue;
                }

                if (target.InstanceID == entity.InstanceID)
                {
                    isTrue = true;
                    break;
                }
            }

            return isTrue;
        }
    }
}